package cn.le.netty.client;

import cn.le.netty.client.handler.EchoClientHandler;
import cn.le.netty.messagepack.MessagePackDecoder;
import cn.le.netty.messagepack.MessagePackEncoder;
import cn.le.util.info.HostInfo;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.codec.LengthFieldPrepender;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.util.CharsetUtil;
public class EchoClient {

    public void run(){
        //1.如果现在客户端不同,那么也可以不适用多线程模式来处理
        //在netty中考虑到代码的统一性,也允许你在客户端设置线程池
        EventLoopGroup group = new NioEventLoopGroup();
        try {
            Bootstrap client = new Bootstrap();//创建客户端
            client.group(group).channel(NioSocketChannel.class)
                    .option(ChannelOption.TCP_NODELAY,true)//允许接受大块的数据返回
                    .handler(new ChannelInitializer<SocketChannel>() {
                        protected void initChannel(SocketChannel socketChannel) throws Exception {
                            //追加拆包器
                            //socketChannel.pipeline().addLast(new LineBasedFrameDecoder(20));
                            socketChannel.pipeline().addLast(new StringEncoder(CharsetUtil.UTF_8));
                            socketChannel.pipeline().addLast(new StringDecoder(CharsetUtil.UTF_8));
                            socketChannel.pipeline().addLast(new EchoClientHandler());
                        }
                    });
            ChannelFuture channelFuture = client.connect(HostInfo.HOST_NAME,HostInfo.PORT).sync();//等待链接处理
            /*channelFuture.addListener(new GenericFutureListener<Future<? super Void>>() {
                public void operationComplete(Future<? super Void> future) throws Exception {
                    if (future.isSuccess()){
                        System.out.println("服务器链接已完成,可以确保进行消息的发送");
                    }
                }
            });*/
            channelFuture.channel().closeFuture().sync();//等待关闭链接
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            group.shutdownGracefully();
        }
    }

    public void objRum() {
        EventLoopGroup group = new NioEventLoopGroup();
        try {
            Bootstrap client = new Bootstrap();//创建客户端
            client.group(group).channel(NioSocketChannel.class)
                    .option(ChannelOption.TCP_NODELAY, true)//允许接受大块的数据返回
                    .handler(new ChannelInitializer<SocketChannel>() {
                        protected void initChannel(SocketChannel socketChannel) throws Exception {
                            //与对象属性个数一致
                            socketChannel.pipeline().addLast(new LengthFieldBasedFrameDecoder(65535,0,4
                                    ,0,4));
                            socketChannel.pipeline().addLast(new MessagePackDecoder());
                            socketChannel.pipeline().addLast(new LengthFieldPrepender(4));//与属性的个数保持一致
                            socketChannel.pipeline().addLast(new MessagePackEncoder());

                            //socketChannel.pipeline().addLast(MarshallingCodeFactory.buildMarshllingDecoder());
                            //socketChannel.pipeline().addLast(MarshallingCodeFactory.builMarshallingEncoder());

                            socketChannel.pipeline().addLast(new EchoClientHandler());
                        }
                    });
            //绑定端口,等待链接处理
            ChannelFuture channelFuture = client.connect(HostInfo.HOST_NAME, HostInfo.PORT).sync();
            //等待服务端监听端口关闭
            channelFuture.channel().closeFuture().sync();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            //提出释放线程池
            group.shutdownGracefully();
        }
    }

    public static void main(String[] args) {
        //传输字符
        //new EchoClient().run();
        //传输对象
       new EchoClient().objRum();
    }
}
